Datadog による Amazon ECS on AWS Fargate コンテナログ収集のベストプラクティス

Datadog による Amazon ECS on AWS Fargate コンテナログ収集のベストプラクティス

Clock Icon2024.12.05

こんにちは。テクニカルサポートチームのShiinaです。

はじめに

コンテナ環境でのアプリケーション運用において、ログの収集と監視は非常に重要です。
エラーの早期発見や原因調査、セキュリティインシデントの検知など、様々な用途で活用されます。
本記事では、Amazon ECS on AWS Fargate で実行されているコンテナのログを Datadog で収集する2つの方法について、それぞれの特徴や具体的な設定手順を解説します。
AWS FireLens を利用する方法と、CloudWatch Logs 経由で Datadog Forwarder を使用する方法を比較しながら、実装に必要なポイントを説明していきます。

ログの収集方法

Amazon ECS on AWS Fargate で実行されているコンテナログを収集して Datadog に転送する方法は2種類あります。

  • AWS FireLens を利用する方法(Datadog 推奨)
  • CoudWatch Logs に出力したログを Datadog Forwarder でルーティングする方法

収集方法の比較

AWS FireLens を利用する方法

  • メリット
    ・リアルタイム性が高く、CloudWatch Logs のコストが不要
    ・専用パイプラインを利用できるため、検索性・可視性が向上
  • デメリット
    ・設定が難しく、Fluent Bit の知識が必要
    ・log router コンテナの管理が必要

CoudWatch Logs に出力したログを Datadog Forwarder でルーティングする方法

  • メリット
    ・設定が簡単で AWS 標準の運用に適合
    ・他の AWS サービスとの連携が可能
  • デメリット
    ・レイテンシーが高く、追加コストが発生
    ・検索性・可視性向上にはパイプライン設定が必要

選択のポイント

・コスト重視・リアルタイム性 → AWS FireLens を利用する方法
・シンプルさ・AWS 標準運用 → CoudWatch Logs に出力したログを Datadog Forwarder でルーティングする方法

実際の監視要件や運用要件に照らし合わせて選択してください。

事前準備

いずれのログ収集方法でも共通して必要となる設定を事前に行なっておきます。

1.Datadog API キーのシークレット登録

コンテナの環境変数やオプションパラメータに Datadog API キーを指定する際は、情報を直接含めないことが重要です。
AWS Secrets Manager に Datadog API キーを登録し、シークレット値を参照する形で安全に利用するのがベストプラクティスです。

AWS Secrets Manager メニューのシークレットより、「新しいシークレットを保存する」を選択します。
次のように設定の上、シークレットを登録します。

  • シークレットタイプ:その他のシークレットのタイプ
  • キー/値のペア:プレーンテキスト
    {"":""}をクリアし、Datadog API キーを入力します。
  • シークレットの名前
     任意の名前を入力します。
  • ローテーションを設定
    オプションの設定不要です。
    シークレット保存

シークレット保存2

登録後はシークレット一覧より名前を選択し、シークレットの ARN を確認します。
設定手順で利用する場面がありますので ARN は控えておいてください。
シークレット保存3

2.タスク実行ロール作成

Amazon ECS on AWS Fargate コンテナメトリクスやログ収集に必要となるタスク実行ロールを作成します。
IAM メニューのロールより、「ロールの作成」を選択します。
次のように設定の上、ロールを作成します。

  • サービスまたはユースケース:Elastic Container Service
  • ユースケース:Elastic Container Service Task
  • 許可ポリシー:AmazonECSTaskExecutionRolePolicy
    ロール作成

ロール作成後、上記マネージドポリシーに不足している、次の権限はインラインポリシーにて追加を行います。

  • CloudWatch Logs ロググループ作成に必要なアクセス
CreateLogGroupPolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
  • Datadog エージェントが Amazon ECS on AWS Fargate コンテナメトリクス収集に必要なアクセス
DatadogECSMetricsGetPolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ecs:ListContainerInstances",
                "ecs:DescribeContainerInstances",
                "ecs:ListClusters"
            ],
            "Resource": "*"
        }
    ]
}
  • AWS Secrets Manager からシークレット値の取得に必要なアクセス
DatadogAPIKeySecretsGetPolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:xxxxxxxxxxx"
        }
    ]
}

ecsTaskExecutionRole-IAM-Global-12-05-2024_01_33_PM

3.タスク実行ロール設定

タスク定義パラメータのexecutionRoleArnパラメータに作成したタスク実行ロールの ARN を指定します。

{
    "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/xxxxxx:nn",
    "containerDefinitions": [

(中略)

  ],
    "family": "FireLens",
    "executionRoleArn": "arn:aws:iam::xxxxxxxxxxxx:role/xxxxxxxxx",
(中略)

タスク定義コンテナ-taskrole

AWS FireLens を利用する方法

設定の流れ

Fluent Bit を使用した FireLens ログルーターコンテナをタスク定義に追加します。
アプリケーションコンテナのログを AWS FireLens 経由で Datadog のログエンドポイントに送信する設定を行います。
必要に応じて、Datadog サイドカーコンテナにも同様のログ構成を適用します。

1.Fluent Bit FireLens ログルーターコンテナ追加

タスク定義パラメータのcontainerDefinitionsにコンテナを追加します。
イメージはpublic.ecr.aws/aws-observability/aws-for-fluent-bit:stableを利用します。
なお、ログルータコンテナ自体のログは awslogs ログドライバーで CoudWatch Logs に出力となります。

  • firelensConfigurationパラメータ
    typeパラメータはfluentbitを指定します。
    ・options のenable-ecs-log-metadatatrueを指定します。
  • logConfigurationパラメータ
    ・ログドライバーはawslogsを指定します。
    ・options のawslogs-group awslogs-region awslogs-stream-prefixパラメータで出力先となる リージョン、CloudWatchLogs ロググループ名、プレフィックスを指定します。
(中略)
        {
            "name": "log_router",
            "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
            "cpu": 0,
            "memoryReservation": 51,
            "portMappings": [],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "user": "0",
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/ecs-aws-firelens-sidecar-container",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "firelens"
                },
                "secretOptions": []
            },
            "systemControls": [],
            "firelensConfiguration": {
                "type": "fluentbit",
                "options": {
                    "enable-ecs-log-metadata": "true"
                }
            }
        }
(中略)

タスク定義コンテナ-router

2.アプリケーションコンテナのログ構成設定

アプリケーションコンテナの例として、nginx に対するログ構成設定を行います。

  • logConfigurationパラメータ
    ・ログドライバーはawsfirelenを指定します。
    optionsパラメータでは下表の Datadog オプションを追加します。
    secretOptionsパラメータでは シークレットの ARN を指定します。
  • dependsOnパラメータ
    ・Fluent Bit FireLens ログルーターコンテナが開始されていることを条件とする依存関係を指定します。

Datadog オプション

キー 設定値 パラメータ説明 補足
Name datadog 出力先
Host http-intake.logs.datadoghq.com Datadog ログ送信先エンドポイント名
TLS on 通信プロトコル 安全な通信のためonが推奨です。
apikey xxxxx Datadog のAPIキー
compress gzip ペイロードの圧縮 gzip圧縮が推奨です。
dd_service webserver ログ生成するサービス名 サーバーの用途や役割などのわかりやすい名称での設定が推奨です。
dd_source nginx ログ生成するソース名 ログ管理に利用されるため、ソース元となるアプリケーションやサービスの名称を設定します。
dd_message_key log message 属性に再マップする属性のキー 特にカスタマイズを行わない場合はlogを設定します。
dd_tags env:prd ログに付与するタグ 環境の区別のためenvタグの付与が推奨です。
provider ecs プロバイダー
(中略)
        {
            "name": "nginx",
            "image": "public.ecr.aws/docker/library/nginx:latest",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "80",
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "dependsOn": [
                {
                    "containerName": "log_router",
                    "condition": "START"
                }
            ],
            "logConfiguration": {
                "logDriver": "awsfirelens",
                "options": {
                    "dd_message_key": "log",
                    "compress": "gzip",
                    "provider": "ecs",
                    "dd_service": "webserver",
                    "Host": "http-intake.logs.datadoghq.com",
                    "TLS": "on",
                    "dd_source": "nginx",
                    "dd_tags": "env:prd",
                    "Name": "datadog"
                },
                "secretOptions": [
                    {
                        "name": "apikey",
                        "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:xxxxxxxxxxx"
                    }
                ]
            },
            "systemControls": []
        }
(中略)

タスク定義コンテナnginx

タスク定義コンテナnginx2

3.Datadog サイドカーコンテナのログ構成設定(任意)

Datadog サイドカーコンテナに対してもログ構成設定を行うことで、Datadog エージェントログも Datadog に送信することができます。
datadog-agent に対してログ構成設定を行います。

  • secretsパラメータ
    ・シークレットの ARN を指定します。
  • logConfigurationパラメータ
    ・ログドライバーはawsfirelenを指定します。
    optionsパラメータでは次の Datadog オプションを追加します。
    secretOptionsパラメータではシークレットの ARN を指定します。
  • dependsOnパラメータ
    ・Fluent Bit FireLens ログルーターコンテナが開始されていることを条件とする依存関係を指定します。
(中略)
   {
            "name": "datadog-agent",
            "image": "public.ecr.aws/datadog/agent:latest",
            "cpu": 0,
            "portMappings": [],
            "essential": false,
            "environment": [
                {
                    "name": "ECS_FARGATE",
                    "value": "true"
                }
            ],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "secrets": [
                {
                    "name": "DD_API_KEY",
                    "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:xxxxxxxxxxx"
                }
            ],
            "dependsOn": [
                {
                    "containerName": "log_router",
                    "condition": "START"
                }
            ],
            "logConfiguration": {
                "logDriver": "awsfirelens",
                "options": {
                    "dd_message_key": "log",
                    "compress": "gzip",
                    "provider": "ecs",
                    "dd_service": "datadog-agent",
                    "Host": "http-intake.logs.datadoghq.com",
                    "TLS": "on",
                    "dd_source": "datadog-agent",
                    "dd_tags": "env:prd",
                    "Name": "datadog"
                },
                "secretOptions": [
                    {
                        "name": "apikey",
                        "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:xxxxxxxxxxx"
                    }
                ]
            },
            "systemControls": []
        }
(中略)

タスク定義コンテナdatadog-1

タスク定義コンテナdatadog-2

4.ログメッセージの確認

Log Explorer でログを確認します。
一覧にコンテナのログが表示されていれば問題なく収集されています。
FireLens for Amazon ECS収集

ログソースは nginx となっています。
パイプラインが利用されており、様々な属性が付与されています。
dd_tagsで指定したenv:prdというタグも付与されているのが確認できます。
ログ属性firelens2

CoudWatch Logs に出力したログを Datadog Forwarder でルーティングする方法

設定の流れ

AWS から Datadog にログを送信する Lambda 関数(Datadog Forwarder)を作成します。
awslogs ログドライバーを使用し、CloudWatch Logs にログを出力する設定を行います。
出力先の CloudWatch Logs ロググループにサブスクリプションフィルターを設定し、ログを Datadog にルーティングします。
必要に応じて、Datadog サイドカーコンテナにも同様のログ構成とサブスクリプションフィルター設定を適用します。

1.Datadog Forwarder 作成

下記 URL からスタック作成を行います。
https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?stackName=datadog-forwarder&templateURL=https://datadog-cloudformation-template.s3.amazonaws.com/aws/forwarder/latest.yaml

DdApiKeyパラメータに Datadog APIキーを入力します。
スタック作成

AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。にチェックを入れ、「スタックの作成」をクリックします。

スタック作成2

作成が完了するまで待ちます。
スタックが CREATE_COMPLETE となると、Lambda 関数「datadog-forwarder-Forwarder-xxxxxxx」が作成されます。

2.アプリケーションコンテナのログ構成設定

アプリケーションコンテナの例として、nginx に対するログ構成設定を行います。

  • logConfigurationパラメータ
    ・ログドライバーはawslogsを指定します。
    ・options のawslogs-group awslogs-region awslogs-stream-prefixパラメータで出力先となる リージョン、CloudWatchLogs ロググループ名、プレフィックスを指定します。
(中略)
        {
            "name": "nginx",
            "image": "public.ecr.aws/docker/library/nginx:latest",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "80",
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/Forwarder/nginx",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
(中略)

タスク定義コンテナ-awslog-nginx1

3.アプリケーションコンテナのログに対するサブスクリプションフィルター設定

出力先となる CloudWatchLogs ロググループに対して、サブスクリプションフィルターの設定を行います。
CloudWatch メニューのロググループより、グループを選択します。
アクションから「Lambda サブスクリプションフィルターを作成」をクリックします。
作成した Datadog Forwarder を送信先の Lambda 関数に指定します。
任意のサブスクリプションフィルタ名を入力し、「ストリーミングを開始」を選択します。

サブスクリプションフィルタ作成nginx

4.Datadog サイドカーコンテナのログ構成設定(任意)

Datadog サイドカーコンテナに対してもログ構成設定を行うことで、Datadog エージェントログも Datadog に送信することができます。
datadog-agent に対してログ構成設定を行います。

  • logConfigurationパラメータ
    ・ログドライバーはawslogsを指定します。
    ・options のawslogs-group awslogs-region awslogs-stream-prefixパラメータで出力先となる リージョン、CloudWatchLogs ロググループ名、プレフィックスを指定します。
(中略)
        {
            "name": "datadog-agent",
            "image": "public.ecr.aws/datadog/agent:latest",
            "cpu": 0,
            "portMappings": [],
            "essential": false,
            "environment": [
                {
                    "name": "ECS_FARGATE",
                    "value": "true"
                }
            ],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "secrets": [
                {
                    "name": "DD_API_KEY",
                    "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:xxxxxxxxxxx"
                }
            ],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/Forwarder/datadog-agent",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
(中略)

タスク定義コンテナ-awslog-datadog1

タスク定義コンテナ-awslog-datadog2

5.Datadog エージェントのログに対するサブスクリプションフィルター設定(任意)

出力先となる CloudWatchLogs ロググループに対して、サブスクリプションフィルターの設定を行います。
CloudWatch メニューのロググループより、グループを選択します。
アクションから「Lambda サブスクリプションフィルターを作成」をクリックします。
作成した Datadog Forwarder を送信先の Lambda 関数に指定します。
任意のサブスクリプションフィルタ名を入力し、「ストリーミングを開始」を選択します。

サブスクリプションフィルタ作成

6.ログメッセージの確認

Log Explorer でログを確認します。
一覧にコンテナのログが表示されていれば問題なく収集されています。
forwarder log確認

ログソースは CloudWatch となっています。
そのため、nginx のパイプラインが利用されません。
メッセージのパースが行われず、重要度もinfoとなっています。
ログ属性cloudwatch

上記のログに対してもパイプラインとプロセッサーを利用することでメッセージのパースおよび重要度の割り当てを行うことが可能です。
詳細は以下をご参考ください。
https://dev.classmethod.jp/articles/datadog-pipelines-processors-guide/

まとめ

Amazon ECS on AWS Fargate で実行されているコンテナログを Datadog に収集する方法は以下の2つです。

  • AWS FireLens を利用する方法(Datadog 推奨)
    リアルタイム性が高くコスト効率が良いが、設定が複雑。
  • CoudWatch Logs に出力したログを Datadog Forwarder でルーティングする方法
    設定が簡単で AWS との親和性が高いが、レイテンシーや追加コストが発生。

監視や運用要件に応じて適切な方法を選択してください。
Datadog API キーは AWS Secrets Manager に登録して安全に利用するのがベストプラクティスです。

本記事が誰かのお役に立てれば幸いです。

参考

https://docs.datadoghq.com/integrations/ecs_fargate/?tab=webui#log-collection
https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/datadog
https://docs.fluentbit.io/manual/pipeline/outputs/datadog
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/using_firelens.html
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/secrets-envvar-secrets-manager.html

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.